Home
I am no expert when I comes to building websites. My last attempt a couple years ago was okay, but I was not fully happy with it. I did not have a good grasp of exactly how all the parts of hosting the site were coming together, and the site itself was stale. I knew going into this rebuild project I did not want to use JavaScript, PHP or Appache2 again as they frustrated me. I have been using Rust a lot recently so it was an easy first choice of what I wanted to use for my backend.
After a quick search for "rust web server crate" I found Rocket; and I also found a bonus crate called Diesel for working with databases. Rocket is a web framework crate for rust that is fast and simple which was great for me to get the site built quickly; I had a static page up in not time. The only real problem I encountered was hosting static content, CSS and images, while also using using address wild cards. I have a full wildcard setup to catch addresses with invalid pages:
#[get("/<_..>")]
fn home_redirect() -> Redirect {
Redirect::to(uri!(home()))
}
I could load my pages but my static folder content would not load, thus I had no CSS formatting. The solution was to add a rank to the static content that proceeds the wildcard default rank. The wildcard route has a default rank of -2 while the static content using StaticFiles::from(...)
defaults to 10, so my calls to static content where being intercepted by the wildcard redirect. Adding a rank of -10 to my static content mount StaticFiles::from(...).rank(-10)
fixed my problem.
My old website was routed internally with Appache2, I knew going into this project that I did not want to work with it again. I found the simpler(?) alternative of nginx. Nginx felt more right to me immediately as I began to learn it. It is way more simple for me to understand; this may be because I have experience with Appache2 and a stronger grasp of how hosting a server works now, but I also like the config files of nginx way better than Appache2's. Since this is my personal portfolio website it is nice to have something I like to use and understand. I did have a pain getting the ssl to work as I kept getting 400 errors when I tried to connect via https or had a reroute from http to https. After about 4 days of swapping between working on ssl and other parts of the server and website I finally realized that for my listen configuration I had typed 433 instead of the default https port 443... I had to take a mental brake after that epiphany. You'd think that I would take time to reread my code slowly and walk through it step by step, double checking hard-coded values by now, but the curse of off by one character issues still plagues me.
Diesel was more of a learning curve, but the "getting started" docs got me going quickly. I had a time figuring out how I wanted to index into single blog posts. I initially decided to use the publish date of the blogs, which was a terrible decision. If I wanted to post twice in one day both blog posts would be selected and that caused a ripple effect of problems when rendering blog pages. So, I swapped to using the title; which did require me to parse my raw markdown files for the first header, but that was less painful than I thought it would be. I was especially happy with how easy it was for me to write functions to query the database and do CRUD operations. For example for when there are more blog posts, I have a function that will get the n
most recent posts sorted by date:
pub fn get_n_recent_posts(connection: &mut SqliteConnection, n: i64) -> Result<Vec<Post>> {
if n <= 0 {
return Ok(vec![]);
}
use crate::schema::posts;
use crate::schema::posts::dsl::*;
let raw_results = posts::table
.limit(n)
.order(published_date.desc())
.order(last_modified_time.desc())
.select(Post::as_select())
.load(connection);
return match raw_results {
Ok(post_vec) => Ok(post_vec),
Err(_) => bail!("No results"),
}
}
Note: I am using anyhow for simple error chaining.
If I need to make a Rust application with a database in the future I will definitely want to use Diesel again!
There is a rust crate compatible with Rocket: Maud, that adds macros for writing dynamic html blocks in rust. I was very happy to use Maud as it let me break apart the different parts of the site into separate functions, letting me work on them in chunks. It also gave me a simple way to add a bit of dynamic naming to the site and write helper functions so that future modification of the site will be simple and quick!
I have worked with CSS before in my undergrad for a GUR credit, and when I built the old version of my website. It is just as fiddly as I remembered. I did more with flex and grid display options this time around, and I feel more comfortable with getting items on the screen where I want them now. The recent blogs section and the featured projects section on the homepage both use grid and flex display options to get the content lined up in a row and the internal tags aligned nicely. I am also using flex to align my social links in the footer. If you want to see the setup you can checkout the file your browser fetched, "default.css", using an inspector (usually opened using f12 depending on your browser.)
I desperately need to refactor the code base of the website. I kept it mostly organized line by line but I need to separate some of the code into different files and factor out some code as functions. The main file is especially egregious, I plan to divide each section of the site into its own file and have the main file compile everything together without having html macros in it at all. Another consideration is to make a mobile friendly version of the CSS; which I know the current standard is to do mobile development first. However, I believe this site's audience is more likely to visit on a PC as it is only "advertised" to recruiters and schools through my resume. I also want to populate the database with more blog posts to flush out the site more. I plan to be writing about projects I work on and big life events relevant to the site (i.e. my education and professional advancements.)
Until next time...
- Nick